<template>
  <v-page
    :background="dynamicContent?.backgroundColor ?? '#f5f6fa'"
    :loading="loading"
    @scroll="scrollHandle"
    @tolower="getProductList"
  >
    <template #header>
      <v-navbar
        :border="false"
        :icon-color="isIndexPage ? 'white' : 'black'"
        :color="isIndexPage ? 'white' : 'black'"
      >
        <view class="title" :style="titleStyle">
          店铺详情
        </view>
      </v-navbar>
      <template v-if="isIndexPage">
        <view class="index-background">
          <v-image
            width="100vw"
            mode="widthFix"
            oss-src="store-page-index-background.png"
          />
        </view>
        <view class="merchant-pad" :style="padStyle">
          <view class="merchant-container" :style="containerStyle">
            <v-image
              height="80rpx"
              width="80rpx"
              border-radius="50%"
              :src="merchant?.logo_image"
              mode="aspectFill"
            />
            <view class="merchant-info" :style="contentStyle">
              <view class="merchant-name">
                {{ merchant?.name }}
              </view>
              <view class="merchant-content">
                <view class="merchant-tag">
                  <view class="left-part">
                    <v-icon
                      size="20rpx"
                      src="@/static/icons/landing-page-vip.svg"
                    />
                  </view>
                  <view class="right-part">
                    认证商家
                  </view>
                </view>
                <view
                  v-if="typeof merchant?.score === 'number'"
                  class="merchant-rate"
                >
                  <wd-rate
                    :model-value="merchant.score / 2"
                    readonly
                    allow-half
                  />
                </view>
              </view>
            </view>
          </view>
        </view>
        <view class="tabs-container" :style="tabsContainerStyle">
          <view
            class="tabs-item"
            :class="{ active: tabIndex === 0 }"
            @click="changeTabIndex(0)"
          >
            首页
          </view>
          <view
            class="tabs-item"
            :class="{ active: tabIndex === 1 }"
            @click="changeTabIndex(1)"
          >
            宝贝
          </view>
        </view>
      </template>
    </template>
    <template #default>
      <view
        class="page-container"
        :style="{
          backgroundColor: dynamicContent?.backgroundColor ?? '#f5f6fa'
        }"
      >
        <template v-if="tabIndex === 0">
          <view v-if="dynamicContent?.backgroundImage" class="page-background">
            <v-image
              width="100vw"
              mode="widthFix"
              :src="dynamicContent?.backgroundImage"
            />
          </view>
          <view class="component-list">
            <template v-for="(component, index) in components" :key="index">
              <store-page-swiper
                v-if="component.el === 'Swiper'"
                :component="component"
                @navigate="navigateHandle"
              />
              <store-page-navigate
                v-else-if="component.el === 'Navigate'"
                :component="component"
                @navigate="navigateHandle"
              />
              <store-page-product
                v-else-if="component.el === 'Product'"
                :component="component"
                :spu-list="storePageData?.spu_list ?? []"
                @click-product="clickProduct"
              />
              <store-page-text
                v-else-if="component.el === 'Text'"
                :component="component"
              />
              <store-page-title
                v-else-if="component.el === 'Title'"
                :component="component"
              />
              <store-page-hotspot
                v-else-if="component.el === 'Hotspot'"
                :component="component"
                @navigate="navigateHandle"
              />
              <store-page-image
                v-else-if="component.el === 'Image'"
                :component="component"
                @navigate="navigateHandle"
              />
            </template>
          </view>
        </template>
        <template v-else-if="tabIndex === 1">
          <view class="header">
            <template v-if="!loading">
              <view
                class="filter-item"
                :class="{ active: filterType === 'QUANTITY' }"
                @click="clickFilter('QUANTITY')"
              >
                <view class="label">
                  销量
                </view>
                <view class="sort-icon">
                  <v-icon
                    :active="filterType === 'QUANTITY' && filterSort === 'ASC'"
                    size="15rpx"
                    :custom-style="{ marginBottom: '-6rpx' }"
                    active-src="@/static/icons/search-sort-arrow-active.svg"
                    src="@/static/icons/search-sort-arrow.svg"
                  />
                  <v-icon
                    :active="filterType === 'QUANTITY' && filterSort === 'DESC'"
                    size="15rpx"
                    :custom-style="{
                      transform: 'rotate(180deg)',
                      marginTop: '-6rpx'
                    }"
                    active-src="@/static/icons/search-sort-arrow-active.svg"
                    src="@/static/icons/search-sort-arrow.svg"
                  />
                </view>
              </view>
              <view
                class="filter-item"
                :class="{ active: filterType === 'TIME' }"
                @click="clickFilter('TIME')"
              >
                <view class="label">
                  新品
                </view>
              </view>
              <view
                class="filter-item"
                :class="{ active: filterType === 'PRICE' }"
                @click="clickFilter('PRICE')"
              >
                <view class="label">
                  价格
                </view>
                <view class="sort-icon">
                  <v-icon
                    :active="filterType === 'PRICE' && filterSort === 'ASC'"
                    size="15rpx"
                    :custom-style="{ marginBottom: '-6rpx' }"
                    active-src="@/static/icons/search-sort-arrow-active.svg"
                    src="@/static/icons/search-sort-arrow.svg"
                  />
                  <v-icon
                    :active="filterType === 'PRICE' && filterSort === 'DESC'"
                    size="15rpx"
                    :custom-style="{
                      transform: 'rotate(180deg)',
                      marginTop: '-6rpx'
                    }"
                    active-src="@/static/icons/search-sort-arrow-active.svg"
                    src="@/static/icons/search-sort-arrow.svg"
                  />
                </view>
              </view>
            </template>
          </view>
          <template v-if="state === 'finished' && productList.length === 0">
            <v-empty text="暂无商品" oss-src="empty-product.png" />
          </template>
          <template v-else>
            <view class="product-list">
              <product-block-double
                v-for="(product, index) in productList"
                :key="index"
                :product="product"
                sub="quantity"
                @click="clickProduct(product)"
              />
            </view>
            <v-loadmore :state="state" @reload="getProductList" />
          </template>
        </template>
      </view>
    </template>
  </v-page>
</template>

<script setup lang="ts">
import useNavbarLayout from '@/composables/use-navbar-layout';
import StorePageHotspot from './modules/store-page-hotspot.vue';
import StorePageSwiper from './modules/store-page-swiper.vue';
import StorePageNavigate from './modules/store-page-navigate.vue';
import StorePageProduct from './modules/store-page-product.vue';
import StorePageText from './modules/store-page-text.vue';
import StorePageTitle from './modules/store-page-title.vue';
import StorePageImage from './modules/store-page-image.vue';
import ProductBlockDouble from './modules/product-block-double.vue';
import type { CSSProperties } from 'vue';

const { navBarHeight, statusBarHeight, menuButtonBounding } = useNavbarLayout();
const menuButtonWidth = computed(() => {
  return menuButtonBounding.value.width + menuButtonBounding.value.right;
});
const headerHeight = computed(() => navBarHeight.value);
const scrollTop = ref(0);
const percentage = computed(() => {
  let percentage = scrollTop.value / (headerHeight.value + 16);
  percentage = Math.min(1, percentage);
  percentage = Math.max(0, percentage);
  return percentage;
});
const titleStyle = computed(() => {
  const styles: CSSProperties = {};
  const opacity = Math.max(0, 1 - percentage.value);
  styles.opacity = opacity;
  styles.fontWeight = 'bold';
  styles.fontSize = '32rpx';
  styles.lineHeight = `${navBarHeight.value}px`;
  if (!isIndexPage.value) return styles;
  styles.color = 'white';
  return styles;
});
const padStyle = computed(() => {
  const styles: CSSProperties = {};
  const height = Math.max(0, headerHeight.value - scrollTop.value + 16);
  styles.height = `${height}px`;
  const from = 12;
  const to = 0;
  styles.paddingBottom = `${from + (to - from) * percentage.value}rpx`;
  return styles;
});
const containerStyle = computed(() => {
  const styles: CSSProperties = {};
  const from = {
    scale: 1,
    top: navBarHeight.value + statusBarHeight.value + 8,
    left: uni.upx2px(24),
    right: uni.upx2px(24)
  };
  const to = {
    scale: 0.7,
    top: statusBarHeight.value,
    left: uni.upx2px(70),
    right: menuButtonWidth.value + uni.upx2px(40)
  };
  styles.height = `${headerHeight.value}px`;
  // styles.transform = `scale(${from.scale + (to.scale - from.scale) * percentage.value})`;
  styles.top = `${from.top + (to.top - from.top) * percentage.value}px`;
  styles.left = `${from.left + (to.left - from.left) * percentage.value}px`;
  styles.right = `${from.right + (to.right - from.right) * percentage.value}px`;
  styles.transformOrigin = 'left';
  styles.transform = `scale(${from.scale + (to.scale - from.scale) * percentage.value})`;
  return styles;
});
const contentStyle = computed(() => {
  const styles: CSSProperties = {};
  return styles;
});
const tabsContainerStyle = computed(() => {
  const styles: CSSProperties = {};
  // const form = 32;
  // const to = 0;
  // styles.borderRadius = `${form + (to - form) * percentage.value}rpx ${form + (to - form) * percentage.value}rpx 0 0`;
  styles.borderRadius = '32rpx 32rpx 0 0';
  styles.backgroundColor = dynamicContent.value?.backgroundColor ?? '#f5f6fa';
  return styles;
});

const loading = ref(true);
const merchantId = ref<string>();
const pageId = ref<string>();
const storePageData = ref<StoreDecorationVO>();
const isIndexPage = computed(
  () => storePageData.value?.type === 'STORE_INDEX_PAGE'
);
const dynamicContent = computed<StorePageDynamicContent | undefined>(() => {
  try {
    if (!storePageData.value?.dynamic_content) return undefined;
    return JSON.parse(storePageData.value.dynamic_content);
  } catch {
    return undefined;
  }
});
const components = computed(
  () => dynamicContent.value?.component_content ?? []
);

const getMerchantIndex = async () => {
  if (!merchantId.value) return;
  const response = await $api.getStoreDecorationStoreIndexPage({
    merchant_id: merchantId.value
  });
  switch (response.__error) {
    case undefined:
      storePageData.value = response.data;
      break;
  }
};
const merchant = ref<MerchantVO>();
const getMerchant = async () => {
  if (!merchantId.value) return;
  const response = await $api.getMerchantId(merchantId.value);
  switch (response.__error) {
    case undefined:
      merchant.value = response.data;
      break;
    default:
      merchant.value = undefined;
  }
};

const getStorePageDetails = async () => {
  if (!pageId.value) return;
  const response = await $api.getStoreDecorationDetailId(pageId.value);
  switch (response.__error) {
    case undefined:
      storePageData.value = response.data;
      break;
  }
};
onLoad(async (query) => {
  merchantId.value = query?.merchant as string | undefined;
  pageId.value = query?.id as string | undefined;

  loading.value = true;
  if (pageId.value) {
    await getStorePageDetails();
    merchantId.value = storePageData.value?.merchant_id;
    await getMerchant();
  } else {
    await Promise.all([getMerchantIndex(), getMerchant()]);
  }
  loading.value = false;
  if (!storePageData.value) uni.navigateBack();
});

const tabIndex = ref(0);
const changeTabIndex = (index: number) => {
  tabIndex.value = index;
  if (index === 1) {
    getProductList();
  }
};

const filterType = ref<'DEFAULT' | 'QUANTITY' | 'PRICE' | 'TIME'>('DEFAULT');
const filterSort = ref<'ASC' | 'DESC'>('ASC');
const clickFilter = (type: 'DEFAULT' | 'QUANTITY' | 'PRICE' | 'TIME') => {
  if (type !== filterType.value) {
    filterType.value = type;
    filterSort.value = 'DESC';
    refreshHandle();
  } else if (type !== 'TIME') {
    filterSort.value = filterSort.value === 'ASC' ? 'DESC' : 'ASC';
    refreshHandle();
  }
};
const refreshing = ref(false);
const refreshHandle = async () => {
  pageIndex.value = 1;
  productList.value = [];
  state.value = undefined;
  refreshing.value = true;
  await getProductList();
  refreshing.value = false;
};

const productList = ref<SpuVO[]>([]);
const total = ref(0);
const pageIndex = ref(1);
const state = ref<'loading' | 'finished' | 'error'>();
const getProductList = async () => {
  if (!isIndexPage.value) return;
  if (state.value !== undefined && state.value !== 'error') return;
  state.value = 'loading';
  const response = await $api.getSearchMerchant({
    page_no: pageIndex.value,
    page_size: 20,
    merchant_id: merchantId.value,
    sort: filterType.value,
    mode: filterSort.value
  });
  switch (response.__error) {
    case undefined:
      productList.value.push(...(response.data?.list ?? []));
      pageIndex.value++;
      if (productList.value.length >= response.data?.total) {
        state.value = 'finished';
      } else {
        state.value = undefined;
      }
      total.value = response.data.total;
      break;
    default:
      state.value = 'error';
  }
};

const clickProduct = (product: SpuVO) => {
  navigateHandle('product', product.id);
};
const navigateHandle = (event: string, value: string | undefined) => {
  if (!value) return;
  const pages = getCurrentPages();
  const method = pages.length >= 8 ? uni.redirectTo : uni.navigateTo;
  if (event === 'page') {
    method({
      url: `/pages/store/store-page?id=${value}`
    });
  } else if (event === 'product') {
    const storePageId = storePageData.value?.id;
    method({
      url: `/pages/product/product-details?id=${value}&storeid=${storePageId}&from=store`
    });
  }
};

const scrollHandle = (e: ScrollEvent) => {
  scrollTop.value = e.detail.scrollTop;
};
</script>

<style lang="scss" scoped>
.index-background {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
}
.merchant-pad {
  .merchant-container {
    position: absolute;
    display: flex;
    align-items: center;
    gap: 0 16rpx;
  }
  .merchant-info {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 8rpx;
    .merchant-name {
      font-size: 36rpx;
      max-width: 100%;
      font-weight: bold;
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
      word-break: break-all;
      color: white;
    }
    .merchant-content {
      gap: 8rpx;
      display: flex;
      align-items: center;
    }
    .merchant-tag {
      position: relative;
      padding: 0 2rpx;
      height: 36rpx;
      line-height: 36rpx;
      border-radius: 6rpx;
      background-color: #333333;
      display: flex;
      align-items: center;
      gap: 8rpx;
      overflow: hidden;
      .left-part {
        position: relative;
        height: 36rpx;
        width: 36rpx;
        display: flex;
        align-items: center;
        justify-content: center;
        z-index: 2;
      }
      .right-part {
        position: relative;
        font-size: 26rpx;
        white-space: nowrap;
        z-index: 2;
      }
      &::after {
        content: '';
        position: absolute;
        top: 50%;
        left: 72rpx;
        height: 200rpx;
        width: 200rpx;
        border-radius: 8rpx;
        transform: translate(0, -50%) rotate(45deg);
        background-color: #ffe5b3;
      }
    }
    .merchant-rate {
      :deep(.wd-rate) {
        display: block;
        white-space: nowrap;
      }
      :deep(.wd-rate__item) {
        margin-right: 2px !important;
      }
    }
  }
}
.tabs-container {
  position: relative;
  z-index: 1;
  border-radius: 32rpx 32rpx 0 0;
  padding: 24rpx;
  display: flex;
  align-items: center;
  gap: 40rpx;
  .tabs-item {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 56rpx;
    width: 80rpx;
    font-size: 28rpx;
    color: #999999;
    transition: all 0.15s;
    &::after {
      position: absolute;
      bottom: -12rpx;
      left: 50%;
      transform: translateX(-50%);
      content: '';
      height: 6rpx;
      width: 0rpx;
      border-radius: 6rpx;
      background-color: #ff2f3b;
      transition: all 0.15s;
    }
    &.active {
      font-weight: bold;
      font-size: 40rpx;
      color: #333333;
      &::after {
        width: 36rpx;
      }
    }
  }
}
.page-container {
  position: relative;
  min-height: 100%;
  .page-background {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: fit-content;
  }
}
.component-list {
  display: flex;
  flex-direction: column;
  gap: 24rpx;
}
.header {
  padding: 0 24rpx 12rpx;
  display: flex;
  align-items: center;
  gap: 30rpx;
  height: 70rpx;
  .filter-item {
    line-height: 70rpx;
    padding: 0 12rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8rpx;
    &.active {
      color: #ff2f3b;
    }
    .sort-icon {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      gap: 2rpx;
      .desc {
        transform-origin: center;
        transform: rotate(180deg);
      }
    }
  }
}
.product-list {
  display: flex;
  flex-wrap: wrap;
  gap: 16rpx 0;
  padding: 0 24rpx;
  justify-content: space-between;
}
</style>
